package com.jason.measure.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * @DESC:   自定义viewgroup 定义自己的margin
 * @Author: Jason
 * @Date: 2016/10/17
 * @Time: 下午5:26
 */

public class CustomLayout4 extends ViewGroup {


    public CustomLayout4(Context context, AttributeSet attrs) {
        super(context, attrs);


    }

    /**
     * Margins是由父容器来处理，而我们的CustomLayout中并没有对其做任何的处理，那么我们应该怎么做呢？
     * 首先要知道Margins封装在LayoutParams中，
     * 如果我们想实现自己对其的处理那么我们必然也有必要实现自己布局的LayoutParams
     */
    public static class CustomLayoutParams extends MarginLayoutParams {



        public CustomLayoutParams(LayoutParams source) {
            super(source);
        }

        public CustomLayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public CustomLayoutParams(int width, int height) {
            super(width, height);
        }

        public CustomLayoutParams(MarginLayoutParams source) {
            super(source);
        }


    }

    /**
     * 生成默认的布局参数
     */
    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new CustomLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    /**
     * 生成布局参数
     * 将布局参数包装成我们自己的
     *
     * @param p
     */
    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new CustomLayoutParams(p);
    }

    /**
     * 生成布局参数
     * 从属性配置中生成我们的布局参数
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new CustomLayoutParams(getContext(), attrs);
    }


    /**
     * 检查当前布局参数是否是我们定义的类型 这在code声明布局参数时常常用到
     */
    @Override
    protected boolean checkLayoutParams(LayoutParams p) {
        return p instanceof CustomLayoutParams;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        // 声明临时变量存储父容器的期望值
        int parentDesireWidth = 0;
        int parentDesireHeight = 0;

        // 如果有子元素
        if (getChildCount() > 0) {

            // 遍历子元素 并对其进行测量
            for (int i = 0; i < getChildCount(); i++) {
                // 获取子元素
                View child = getChildAt(i);
                // 获取子元素的布局参数
                CustomLayoutParams clp = (CustomLayoutParams) child.getLayoutParams();

                // 测量子元素并考虑外边距
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);

                // 计算父容器的期望值
                parentDesireWidth += child.getMeasuredWidth() + clp.leftMargin + clp.rightMargin;
                parentDesireHeight += child.getMeasuredHeight() + clp.topMargin + clp.bottomMargin;
            }


            // 考虑父容器的内边距
            parentDesireWidth += getPaddingLeft() + getPaddingRight();
            parentDesireHeight += getPaddingTop() + getPaddingBottom();

            // 尝试比较建议最小值和期望值的大小 并取大值
            parentDesireWidth = Math.max(parentDesireWidth, getSuggestedMinimumWidth());
            parentDesireHeight = Math.max(parentDesireHeight, getSuggestedMinimumHeight());

        }

        // 设置最终测量值
        setMeasuredDimension(resolveSize(parentDesireWidth, widthMeasureSpec), resolveSize(parentDesireHeight, heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        // 获取父容器的内边距
        int parentPaddingLeft = getPaddingLeft();
        int parentPaddingTop = getPaddingTop();


        // 判断是否有子元素
        if (getChildCount() > 0) {
            // 声明一个临时变量存储高度倍增值
            int mutilHeight = 0;

            // 遍历子元素并对其进行定位布局
            for (int i = 0; i < getChildCount(); i++) {
                // 获取每个子元素
                View childView = getChildAt(i);

                CustomLayoutParams clp = (CustomLayoutParams) childView.getLayoutParams();

                // 通知子元素进行布局  考虑父容器内边距和子元素外边距的影响
                childView.layout(parentPaddingLeft + clp.leftMargin, mutilHeight + parentPaddingTop + clp.topMargin,
                        childView.getMeasuredWidth() + parentPaddingLeft + clp.leftMargin,
                        childView.getMeasuredHeight() + mutilHeight + parentPaddingTop + clp.topMargin);

                // 改变高度倍增值
                mutilHeight += childView.getMeasuredHeight() + clp.topMargin + clp.bottomMargin;
            }
        }

    }
}
